﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Principal;
using System.Text;
using System.Web;
using System.Web.Mvc;


using Rubik.Tester;

namespace TestingSite.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
            ViewData["Greetings"] = string.Format("Hello, {0}", windowsIdentity.Name);
            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        public ActionResult Upload()
        {
            return View();
        }

        private string ParceTestResult(IEnumerable<SolutionTestResult> testResults)
        {
            StringBuilder result = new StringBuilder();
            int index = 0;
            int resultLength = 0;
            bool isPassed = true;
            foreach (SolutionTestResult solutionTestResult in testResults)
            {
                isPassed &= solutionTestResult.Passed;
                if (solutionTestResult.Passed)
                {
                    if (solutionTestResult.Length > resultLength)
                    {
                        resultLength = solutionTestResult.Length;
                    }
                    result.AppendFormat(" Test #{0}, Passed, Result = {1} bits",
                        ++index,
                        solutionTestResult.Length);
                    result.Append("<br/>");
                }
                else
                {
                    result.AppendFormat(" Test #{0}, Failed, Message: {1}",
                        ++index,
                        solutionTestResult.ErrorMessage);
                    result.Append("<br/>");
                }
            }

            result.AppendFormat("<b>Result:");
            if (isPassed)
            {
                result.AppendFormat(" Passed, Score: {0}<b/>", resultLength);
                result.Append("<br/>");
            }
            else
            {
                result.AppendLine(" Not passed");
                result.Append("<br/>");
            }
            return result.ToString();
        }

        // This action handles the form POST and the upload
        [HttpPost]
        public ActionResult Upload(HttpPostedFileBase file)
        {
            // Verify that the user selected a file
            if (file != null && file.ContentLength > 0)
            {
                StringBuilder result = new StringBuilder();
                try
                {
                    // extract only the fielname
                    var fileName = Path.GetFileName(file.FileName);
                    // store the file inside ~/App_Data/uploads folder
                    var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                    file.SaveAs(path);

                    Assembly assembly = Assembly.LoadFrom(path);

                    RubikSolutionLoader loader = new RubikSolutionLoader();
                    RubikSolutionActivator activator = loader.Load(assembly);

                    RubikTestManager testManager = new RubikTestManager();

                    result.Append("Testing...");
                    result.Append("<br/>");
                    IEnumerable<SolutionTestResult> results = testManager.Test(activator);
                    result.AppendLine(ParceTestResult(results));
                }
                catch (Exception ex)
                {
                    result.AppendLine(ex.Message);
                }
                //todo: use database to store results.
                Session["Message"] = MvcHtmlString.Create(result.ToString());
                
            }
            // redirect back to the index action to show the form once again
            return RedirectToAction("Result");
        }

        public ActionResult Result()
        {
            ViewData["Message"] = Session["Message"];
            return View();
        }

    }
}
